/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Haystack Software Inc. All rights reserved.
 *  Licensed under the PolyForm Strict License 1.0.0. See License.txt in the project root for
 *  license information.
 *--------------------------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See code-license.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as objects from "vs/base/common/objects"
import { ICodeEditor } from "vs/editor/browser/editorBrowser"
import { ICodeEditorService } from "vs/editor/browser/services/codeEditorService"
import {
  CodeEditorWidget,
  ICodeEditorWidgetOptions,
} from "vs/editor/browser/widget/codeEditor/codeEditorWidget"
import {
  ConfigurationChangedEvent,
  IEditorOptions,
} from "vs/editor/common/config/editorOptions"
import { ILanguageConfigurationService } from "vs/editor/common/languages/languageConfigurationRegistry"
import { ILanguageFeaturesService } from "vs/editor/common/services/languageFeatures"
import { IAccessibilityService } from "vs/platform/accessibility/common/accessibility"
import { ICommandService } from "vs/platform/commands/common/commands"
import { IContextKeyService } from "vs/platform/contextkey/common/contextkey"
import { IInstantiationService } from "vs/platform/instantiation/common/instantiation"
import { INotificationService } from "vs/platform/notification/common/notification"
import { IThemeService } from "vs/platform/theme/common/themeService"

export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
  private readonly _parentEditor: ICodeEditor
  private readonly _overwriteOptions: IEditorOptions

  constructor(
    domElement: HTMLElement,
    options: IEditorOptions,
    codeEditorWidgetOptions: ICodeEditorWidgetOptions,
    parentEditor: ICodeEditor,
    @IInstantiationService instantiationService: IInstantiationService,
    @ICodeEditorService codeEditorService: ICodeEditorService,
    @ICommandService commandService: ICommandService,
    @IContextKeyService contextKeyService: IContextKeyService,
    @IThemeService themeService: IThemeService,
    @INotificationService notificationService: INotificationService,
    @IAccessibilityService accessibilityService: IAccessibilityService,
    @ILanguageConfigurationService
    languageConfigurationService: ILanguageConfigurationService,
    @ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService
  ) {
    super(
      domElement,
      {
        ...parentEditor.getRawOptions(),
        overflowWidgetsDomNode: parentEditor.getOverflowWidgetsDomNode(),
      },
      codeEditorWidgetOptions,
      instantiationService,
      codeEditorService,
      commandService,
      contextKeyService,
      themeService,
      notificationService,
      accessibilityService,
      languageConfigurationService,
      languageFeaturesService
    )

    this._parentEditor = parentEditor
    this._overwriteOptions = options

    // Overwrite parent's options
    super.updateOptions(this._overwriteOptions)

    this._register(
      parentEditor.onDidChangeConfiguration((e: ConfigurationChangedEvent) =>
        this._onParentConfigurationChanged(e)
      )
    )
  }

  getParentEditor(): ICodeEditor {
    return this._parentEditor
  }

  private _onParentConfigurationChanged(e: ConfigurationChangedEvent): void {
    super.updateOptions(this._parentEditor.getRawOptions())
    super.updateOptions(this._overwriteOptions)
  }

  override updateOptions(newOptions: IEditorOptions): void {
    objects.mixin(this._overwriteOptions, newOptions, true)
    super.updateOptions(this._overwriteOptions)
  }
}
